
@using Syncfusion.Blazor;
@using Microsoft.AspNetCore.Components;
@using Microsoft.AspNetCore.Components.Routing;

@inject IJSRuntime JsRuntime;
@inject NavigationManager UriHelper;
@inject SampleService SampleService;

@inherits LayoutComponentBase;
@implements IDisposable;

<CascadingValue Value="@this">
    <SpinnerComponent @ref="spinnerRef"></SpinnerComponent>
    @*Set empty layout to home page and components which have open in new window functionality.*@
    @{
        SampleService.Update(UriHelper);
        var isEmptyLayout = SampleService.SampleInfo != null && !UriHelper.Uri.Contains(SampleService.SampleInfo.Url) && SampleService.SampleInfo.MappingSampleName != null;
    }
    @if (SampleUtils.IsHomePage(UriHelper) || isEmptyLayout)
    {
        foreach (var fileName in SampleBrowser.PreLoadFiles)
        {
            <link rel="preload" href="@fileName" as="font" type="font/woff2" crossorigin />
        }
        <CascadingValue Value="isDeviceMode" Name="IsDevice">
            <div>
                @Body
            </div>
        </CascadingValue>
    }
    else
    {
        <div class="sample-browser e-view sf-new" @onclick="OnAppClick">
            <div class="sb-mobile-overlay sb-hide"></div>
            <HeaderComponent @ref="headerRef" OnToggleClick="@OnToggleClick" OnRightToggleClick="@OnRightToggleClick"></HeaderComponent>
            <div class="sb-content e-view">
                <div class="@searchContainer">
                    <div class="index-search-container">
                        <SearchComponent @ref="@searchRef"></SearchComponent>
                    </div>
                </div>
                <LeftPaneComponent @ref="LeftPaneRef"></LeftPaneComponent>
                <RightPaneComponent @ref="RightPaneRef">@Body</RightPaneComponent>
                @if (SampleService.IsDevice)
                {
                    <SideBarComponent IsExpanded="@rightSidebarExpanded" Position="SidebarPlacement.Right">
                        <Preferences IsMainLayout="true"></Preferences>
                    </SideBarComponent>
                    <SampleNavigator @ref="SampleNavigatorRef"></SampleNavigator>
                }
            </div>
        </div>
    }
</CascadingValue>

@code {
    [Inject]
    protected SyncfusionBlazorService SyncfusionService { get; set; }

    private bool isDeviceMode { get; set; }
    private bool isSearchIconClick { get; set; }
    private string searchContainer { get; set; }
    private bool rightSidebarExpanded { get; set; }
    private SpinnerComponent spinnerRef { get; set; }
    private DotNetObjectReference<object> dotnetObjectRef { get; set; }
    private SearchComponent searchRef { get; set; }
    private HeaderComponent headerRef { get; set; }

    /// <summary>
    /// LeftPane reference for outside usage.
    /// </summary>
    public LeftPaneComponent LeftPaneRef { get; set; }
    /// <summary>
    /// RightPane reference for outside usage.
    /// </summary>
    public RightPaneComponent RightPaneRef { get; set; }

    /// <summary>
    /// SampleNavigator reference for outside usage.
    /// </summary>
    public SampleNavigator SampleNavigatorRef { get; set; }

    // Left sidebar click handler
    private async Task OnToggleClick()
    {
        // Update left sidebar expand and collapse status
        this.LeftPaneRef.UpdateExpandedState();
        // Collapse right sidebar if it is expanded
        if (SampleService.IsDevice && rightSidebarExpanded)
        {
            rightSidebarExpanded = !rightSidebarExpanded;
        }
        await JsRuntime.InvokeAsync<string>("callResizeEvent");
    }

    // Right sidebar click handler
    private async Task OnRightToggleClick()
    {
        // Update right sidebar expand and collapse status
        rightSidebarExpanded = !rightSidebarExpanded;
        // Collapse left sidebar if it is expanded
        if (LeftPaneRef.IsExpanded())
        {
            LeftPaneRef.UpdateExpandedState();
        }
        await ShowSearchLayout();
    }

    // App click handler for collapse the sidebar components in device rendering.
    private async Task OnAppClick()
    {
        this.CollapseSideBar();
        headerRef.HidePreferences();
        if (searchRef.IsFocusOut() && !isSearchIconClick)
        {
            // Await the search layout hide process for the search list selection.
            await Task.Delay(200);
            await ShowSearchLayout();
        }
        else
        {
            isSearchIconClick = false;
        }
    }

    // Location change event handler
    private async void LocationChanged(object sender, LocationChangedEventArgs e)
    {
        // Get dynamic resource list.
        var resources = SampleUtils.GetDynamicResources(UriHelper, SampleService);

        if (resources.Count > 0)
        {
            await this.JsRuntime.InvokeVoidAsync("sfBlazorSB.loadResources", resources);
        }
    }

    /// <summary>
    /// Show search layout in the demos page.
    /// </summary>
    public async Task ShowSearchLayout(bool isIconClick = false, bool isEscPressed = false)
    {
        if (isIconClick && searchContainer.Contains(SampleUtils.DISPLAY_NONE))
        {
            isSearchIconClick = isIconClick;
            searchContainer = SampleUtils.RemoveClass(searchContainer, SampleUtils.DISPLAY_NONE);
            await searchRef.InputFocus();
        }
        else
        {
            searchContainer = SampleUtils.AddClass(searchContainer, SampleUtils.DISPLAY_NONE);
        }
        if (isEscPressed)
        {
            StateHasChanged();
        }
    }

    /// <summary>
    /// Collapse both right and left sidebar component.
    /// </summary>
    public void CollapseSideBar()
    {
        if (SampleService.IsDevice)
        {
            // Collapse left sidebar if it is expanded on document click
            if (LeftPaneRef.IsExpanded())
            {
                LeftPaneRef.UpdateExpandedState();
            }
            // Collapse right sidebar if it is expanded on document click
            if (rightSidebarExpanded)
            {
                rightSidebarExpanded = !rightSidebarExpanded;
            }
        }
    }

    /// <summary>
    /// Update BreadCrumb component with current sample details.
    /// </summary>
    /// <param name="componentName">Specifies the current component name.</param>
    /// <param name="category">Specifies the current sample category name.</param>
    /// <param name="sampleName">Specifies the current sample name.</param>
    public void UpdateBreadCrumb(string componentName, string category, string sampleName)
    {
        this.RightPaneRef.BreadCrumbRef?.Refresh(componentName, category, sampleName);
    }

    /// <summary>
    /// Update device mode while resizing window through UI.
    /// </summary>
    /// <param name="isDevice">Specifies the current resolution is device mode or not.</param>
    [JSInvokable]
    public void UpdateDeviceMode(bool isDevice)
    {
        isDeviceMode = isDevice;
        SampleService.IsDevice = isDevice;
        StateHasChanged();
    }

    protected override void OnInitialized()
    {
        base.OnInitialized();
        UriHelper.LocationChanged += LocationChanged;
        // Enable ripple effect to the material theme.
        if (UriHelper.Uri.IndexOf("material") > 0)
        {
            SyncfusionService.EnableRipple();
        }
        searchContainer = SampleUtils.SEARCH_OVERLAY + SampleUtils.SPACE + SampleUtils.DISPLAY_NONE;
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        if (firstRender)
        {
            // Add Spinner ref to the sample servie to get access in SampleBaseComponent class.
            if (SampleService.Spinner == null)
            {
                SampleService.Spinner = spinnerRef;
            }

            dotnetObjectRef = DotNetObjectReference.Create<object>(this);
            // Get device information for mobile sidebar rendering
            this.SampleService.IsDevice = await this.JsRuntime.InvokeAsync<bool>("sfBlazorSB.isDevice", dotnetObjectRef);
            this.isDeviceMode = this.SampleService.IsDevice;
            if (this.SampleService.IsDevice)
            {
                LeftPaneRef?.UpdateExpandedState();
                StateHasChanged();
            }
            // Update home page or demo page loaded property in SampleService.
            SampleUtils.GetDynamicResources(UriHelper, SampleService);
        }
        else
        {
            // Refresh meta data for home page navigation.
            if (UriHelper.BaseUri == UriHelper.Uri)
            {
                SampleService.MetaData?.Refresh();
            }
        }
        if (!this.SampleService.IsDevice)
        {
            // Render sample navigator in the right pane for desktop.
            RightPaneRef?.SampleNavigatorRef.Rerender(SampleService.IsDevice);
        }
    }

    public void Dispose()
    {
        dotnetObjectRef?.Dispose();
        UriHelper.LocationChanged -= LocationChanged;
    }
}

